import json
import time
import uuid
import wave
from typing import List
from websocket import create_connection

import websocket

from common.log import logger

async def send_audio_to_websocket(output_file):
    try:
        websocket_address = "ws://180.184.36.44/asr/v0.8"
        # Open and read the WAV file
        with wave.open(output_file) as f:
            assert f.getsampwidth() == 2
            assert f.getnchannels() == 1
            sample_rate = f.getframerate()
            pcm = f.readframes(f.getnframes())

            items: List[dict] = []
            payload = {
                "sample_rate": 16000,
                "enable_punctuation": True,
                "enable_words": False,
                "max_sentence_silence": 600,
            }
            task_id = str(uuid.uuid1())
            start_msg = {
                "header": {
                    "event_name": "StartTranscription",
                    "task_id": task_id,
                },
                "payload": payload,
            }
            stop_msg = {
                "header": {
                    "event_name": "StopTranscription",
                }
            }

            ws = create_connection(websocket_address, suppress_origin=True)
            ws.send(json.dumps(start_msg))
            resp = ws.recv()
            resp_dict = json.loads(resp)
            if resp_dict["header"]["event_name"] != "TranscriptionStarted":
                raise ""
            step = sample_rate * 1 // 1000 * 2
            start_time = time.time()
            t = 0.0
            for i in range(0, len(pcm), step):
                chunk = pcm[i: i + step]
                t += len(chunk) / 2 / sample_rate
                sleep_time = t - (time.time() - start_time)
                if sleep_time > 0:
                    time.sleep(sleep_time)
                ws.send(chunk, opcode=websocket.ABNF.OPCODE_BINARY)
            else:
                ws.send(pcm, opcode=websocket.ABNF.OPCODE_BINARY)
            ws.send(json.dumps(stop_msg))

            while True:
                resp = ws.recv()
                resp_dict = json.loads(resp)
                event_name = resp_dict["header"]["event_name"]
                if event_name == "SentenceEnd":
                    items.append(resp_dict)
                elif event_name == "TranscriptionCompleted":
                    break
                elif resp_dict["header"]["status"] != 200:
                    pass
            try:
                ws.close()
            except Exception as e:
                logger.error("ws close error: %s" % str(e))

            res = LxAsrOnlineWavResult(items)
            logger.info(f"文件名称{output_file},转换后的内容为{res.sentences()}")
            transfer_result = res.sentences()
            if transfer_result:
                sentence = transfer_result[-1]['sentence']
                return str(sentence)
    except Exception:
        return ""


class LxAsrOnlineWavResult:
    def __init__(self, raw_data: List[dict]):
        self.raw_data = raw_data
        self._sentences = []

    def sentences(self) -> List[dict]:
        if not self._sentences:
            for item in self.raw_data:
                p = item["payload"]
                start_time = p.get("begin_time") or p.get("start_time") or -1
                end_time = p.get("time") or p.get("end_time") or -1
                sentence = p["result"]
                if sentence:
                    a = {
                        "sentence": sentence,
                        "start_time": start_time,
                        "end_time": end_time,
                    }
                    self._sentences.append(a)
        return self._sentences

